module  sdram_init(
        input                   clk             ,

        output          [ 2:0]  cmd             ,
        output          [12:0]  init_addr       ,
        output          [ 1:0]  init_ba         ,

        output  reg             init_end_flag
);

/////////////////////命令 ras_n cas_n we_n
parameter       [2:0]       CMD_LOADMODE  		=       3'b000  ;	
parameter       [2:0]       CMD_AUTO_REFRESH    =       3'b001  ;
parameter       [2:0]       CMD_PRECHARGE 		=       3'b010  ;
parameter       [2:0]       CMD_NOP       		=       3'b111  ;

////////////////////状态
parameter
//初始化
Init_NOP_state                                  =       5'b00001,
Init_PALL_state                                 =       5'b00010,
Init_PALL_state_NOP1_state                      =       5'b10101,
//初始化刷新
Init_Auto_Refresh_state                         =       5'b00011,
Init_Auto_Refresh_NOP1_state                    =       5'b01111,
Init_Auto_Refresh_NOP2_state                    =       5'b10000,
Init_Auto_Refresh_NOP3_state                    =       5'b10001,
Init_Auto_Refresh_NOP4_state                    =       5'b10010,
Init_Auto_Refresh_NOP5_state                    =       5'b10011,
Init_Auto_Refresh_NOP6_state                    =       5'b10100,
//模式寄存器配置
Init_Load_mode_register_state                   =       5'b00100,
Init_Load_mode_register_NOP_state               =       5'b00101,
//空闲
idle_state                                      =       5'b00110;

reg[4:0] current_state;

///////////////////其他参数
//模式寄存器设置
parameter   [12:0]  MODE_REG    =   13'b000_1_00_010_0_000      ;       

parameter 	        POWERUP_DELAY               =       10000   ;   //100us，上电延迟
parameter           AUTO_REFRESH_INIT           =       2       ;   //初始化刷新至少需要2次

integer             count_init_powerup_delay                    ;   //计数100us上电延迟
reg         [1:0]   count_auto_refresh_init     =       1'd0    ;   //计数初始化刷新2次

reg                 powerup_complete_flag       =       1'b0    ;   //上电结束标志


///////////////////主程序
always @(posedge clk)//100us上电延迟

		begin
				if( current_state==Init_NOP_state)
					begin
						
						if (count_init_powerup_delay<POWERUP_DELAY-2)//100 us
							begin
								powerup_complete_flag =1'b0;
								count_init_powerup_delay = count_init_powerup_delay + 1;
							end
						else
							powerup_complete_flag =1'b1;
							
					end
				else
					count_init_powerup_delay=0;
		end
					

always @(posedge clk)//状态机
begin
		
		case (current_state)
			  
			  Init_NOP_state:	//上电延迟100us.
			  begin
				  			
							if (powerup_complete_flag==1'b1)//100us延迟后开始预充电
								begin
									current_state=Init_PALL_state;
								end
							else
								current_state=Init_NOP_state;//等待100us计数
											  
			  end
			  			  
			  Init_PALL_state:
			  begin
						current_state=Init_PALL_state_NOP1_state;
												  
			  end
			  
			  Init_PALL_state_NOP1_state: //TRP 15ns，两个时钟周期
			  begin
					current_state=Init_Auto_Refresh_state;
			  end
			  
			  Init_Auto_Refresh_state: //初始化的刷新需要两次
			  begin
						count_auto_refresh_init<=count_auto_refresh_init+1;
						current_state=Init_Auto_Refresh_NOP1_state;
			  end
				
				Init_Auto_Refresh_NOP1_state:		//tRC 60ns 设置70ns以防意外
				begin
					current_state=Init_Auto_Refresh_NOP2_state;
				end

				Init_Auto_Refresh_NOP2_state:
				begin
					current_state=Init_Auto_Refresh_NOP3_state;
				end

				Init_Auto_Refresh_NOP3_state:
				begin
					current_state=Init_Auto_Refresh_NOP4_state;
				end

				Init_Auto_Refresh_NOP4_state:
				begin
					current_state=Init_Auto_Refresh_NOP5_state;
								
				end
				
				Init_Auto_Refresh_NOP5_state:
				begin
					current_state=Init_Auto_Refresh_NOP6_state;
								
				end
				
                Init_Auto_Refresh_NOP6_state:
				begin
						if (count_auto_refresh_init < AUTO_REFRESH_INIT) 
							current_state=Init_Auto_Refresh_state;
						else
							current_state=Init_Load_mode_register_state;
				end
            Init_Load_mode_register_state:
			begin
					current_state=Init_Load_mode_register_NOP_state;
			end

			Init_Load_mode_register_NOP_state:
			begin
					current_state=idle_state;	//初始化结束
                    init_end_flag=1'b1;
			end    
            idle_state:
            begin
                if(init_end_flag==1'b1)
                    current_state=idle_state;
                else
                    current_state<=Init_NOP_state;
            end
            default : current_state<=idle_state;
        endcase
 end                                   

//命令
assign cmd =(current_state==Init_Load_mode_register_state)?CMD_LOADMODE:
(current_state==Init_PALL_state)?CMD_PRECHARGE:
(current_state==Init_Auto_Refresh_state)?CMD_AUTO_REFRESH:CMD_NOP;

//地址
assign {init_ba,init_addr}=(current_state==Init_PALL_state)? {15{1'b1}}:				//令所有BA[1]+A[12]为1，其中A10必须为高
		 (current_state==Init_Load_mode_register_state)? MODE_REG:{15{1'b0}};			//模式寄存器配置. 


endmodule